from fastapi import APIRouter,Depends
from sqlalchemy import desc,asc,and_
from model.downmine_data import DownmineData
from model.ground_mine import GroundMine
from model.ground_sensor import GroundSensor
from model.equipment import Equipment
from sqlalchemy.orm import Session
from db.mysql import get_db
from vendor.extend.courier import *
from vendor.extend.conversion import is_positive_integer
from vendor.library.strain3d.stress_three import complete_stress_analysis
from datetime import datetime, timedelta

DataBoard = APIRouter()



@DataBoard.get('/sensor')
async def sensor(sensor_id:int=0,start_time:int=0,end_time:int=0, db: Session = Depends(get_db)):
    if not is_positive_integer(sensor_id):
        return Error(msg='传感器id参数错误')
    if end_time<start_time:
        return Error(msg='结束时间不能小于开始时间')
    if not is_positive_integer(start_time):
        end_time=int(time.time())
        start_time=end_time-604800

    sensor=db.query(GroundSensor.id,GroundSensor.colliery_id,GroundSensor.mine_id,GroundSensor.chanel,GroundSensor.coefficient,GroundSensor.stress_matrix,GroundSensor.transformation_matrix,GroundSensor.wavelength).filter_by(id=sensor_id).order_by(desc("id")).first()
    if not sensor:
        return Error(msg='未找到传感器数据')

    return_data={
        'id':sensor.id,
        'colliery_id':sensor.colliery_id,
        'mine_id':sensor.mine_id,
        'chanel':sensor.chanel
    }
    #初始波长截取时间:(小时，多少个小时)
    wavelength=int(sensor.wavelength)
    # 温度补偿系数
    KT=sensor.coefficient

    # 原始数据（Python list 形式）传感器应变标定矩阵（9*6矩阵）：
    D_list=sensor.stress_matrix
    #传感器坐标转换矩阵（3*3矩阵）：
    A_list=sensor.transformation_matrix

    # 生成10个数组
    design_wavelengths=[0 for _ in range(9)]

    # 传入的通道名称数据
    channel_num = sensor.chanel.lower()
    #channel_num='ch2'
    ch2 = channel_num[:2]

    if ch2 !='ch':
        return Error(msg='通道参数错误')
    # 传入的点数
    point_num = 10

    last_data=db.query(DownmineData.create_time).filter_by(line=channel_num).order_by(asc("id")).first()
    if not last_data:
        return Error(msg='没有找到相关数据')

    last_info=db.query(DownmineData.data).filter(and_(DownmineData.line == channel_num,DownmineData.create_time > last_data.create_time+(wavelength*3600))).order_by(asc("id")).first()
    if not last_info:
        return Error(msg='没有找到相关数据')

    # 初始基准波长 (10个参数，第一个是初始温度波长，后面9个是初始应力波长)
    initial_wavelengths = last_info.data[0:point_num]
    # 截取的初始波长 历史数据
    list_data=db.query(DownmineData.id,DownmineData.data,DownmineData.line,DownmineData.create_time).filter_by(line=channel_num).filter(and_(DownmineData.create_time < end_time,DownmineData.create_time > start_time)).order_by(asc("id")).all()

    list_len=len(list_data)
    if list_len>500:
        start = 0
        end = list_len-1
        count = 500
        interval = (end - start) / (count - 1)  # 计算间隔
        keys = [int(start + i * interval) for i in range(count)]
        data_list = [list_data[i] for i in keys]
    else:
        data_list=list_data

    list_data=[]
    for row in data_list:
        measured_wavelengths=row.data[0:point_num]
        # 使用列表切片
        slice_of_numbers = measured_wavelengths[10:20]
        # 检查所有元素是否为0
        all_zero = all(eval(x) == 0 for x in slice_of_numbers)
        if not all_zero:
            continue

        all_positive = all(int(num) > 0 for num in measured_wavelengths)
        if not all_positive:
            continue

        final_data=complete_stress_analysis(
            measured_wavelengths=measured_wavelengths,
            initial_wavelengths=initial_wavelengths,
            KT=KT,
            constitutive_matrix=D_list,
            adjustment_matrix=A_list
        )
        stress=final_data['主应力大小']
        horizontal=final_data['正应力大小'][:3].tolist()

        list_data.append(
            {
                'stress':{
                    'σ1':stress[0],
                    'σ2':stress[1],
                    'σ3':stress[2]
                },
                'direction':final_data['主应力方向'],
                'horizontal':{
                    'σx':horizontal[0][0],
                    'σy':horizontal[1][0],
                    'σz':horizontal[2][0]
                },
                'create_time':row.create_time
            }
            )
    return_data['data_list']=list_data

    return Success(data=return_data)


@DataBoard.get('/column_chart')
async def column_chart(colliery_id:int=0,mine_id:int=0,data_time:int=0, db: Session = Depends(get_db)):
    conditions=[]
    if mine_id>0:
        conditions.append(GroundSensor.mine_id==mine_id)
    if is_positive_integer(colliery_id):
        conditions.append(GroundSensor.colliery_id==colliery_id)

    sensor=db.query(GroundSensor).filter(and_(*conditions)).order_by(desc("id")).all()
    if not sensor:
        return Error(msg='未找到钻孔数据')
    data_list=[]
    for sensor_info in sensor:
        #钻孔信息
        mine=db.query(GroundMine).filter(GroundMine.id==sensor_info.mine_id).order_by(desc("id")).first()
        if not mine:
            continue
        # 生成10个数组
        design_wavelengths=[0 for _ in range(9)]
        #初始波长截取时间:(小时，多少个小时)
        wavelength=int(sensor_info.wavelength)
        # 温度补偿系数
        KT=sensor_info.coefficient
        # 原始数据（Python list 形式）传感器应变标定矩阵（9*6矩阵）：
        D_list=sensor_info.stress_matrix
        #传感器坐标转换矩阵（3*3矩阵）：
        A_list=sensor_info.transformation_matrix
        # 通道
        channel_num=sensor_info.chanel
        stress_info={
            'id':sensor_info.id,
            'colliery_id':sensor_info.colliery_id,
            'mine_id':sensor_info.mine_id,
            'chanel':channel_num,
            'sensor_number':sensor_info.sensor_number,
            'setup_time':sensor_info.setup_time,
            'mine_serial_number':mine.serial_number,
            'sensor':[]
        }
        last_data=db.query(DownmineData.create_time).filter_by(line=channel_num).order_by(asc("id")).first()
        if not last_data:
            continue
            #return Error(msg='没有找到相关数据')
        last_info=db.query(DownmineData.data).filter(and_(DownmineData.line == channel_num,DownmineData.create_time > last_data.create_time+(wavelength*3600))).order_by(asc("id")).first()
        if not last_info:
            continue
            #return Error(msg='没有找到相关数据')

        # 传入的点数
        point_num = 10
        # 初始基准波长 (10个参数，第一个是初始温度波长，后面9个是初始应力波长)
        initial_wavelengths = last_info.data[0:point_num]
        query_conditions=[DownmineData.line==channel_num]
        if data_time>0:
            # 将时间戳转换为datetime对象
            specific_datetime = datetime.fromtimestamp(data_time)
            # 计算第二天的00:00:00
            next_day_midnight = specific_datetime + timedelta(days=1)
            next_day_midnight = next_day_midnight.replace(hour=0, minute=0, second=0, microsecond=0)
            next_time=next_day_midnight.timestamp()
            query_conditions.append(DownmineData.create_time<int(next_time))

        row=db.query(DownmineData).filter(and_(*query_conditions)).order_by(desc("id")).first()

        if row:
            stress=[]
            measured_wavelengths=row.data[0:point_num]
            # 使用列表切片
            slice_of_numbers = measured_wavelengths[10:20]
            # 检查所有元素是否为0
            all_zero = all(eval(x) == 0 for x in slice_of_numbers)
            if not all_zero:
                return Error(msg="光栅数据异常")

            all_positive = all(int(num) > 0 for num in measured_wavelengths)
            if not all_positive:
                return Error(msg="光栅数据异常")

            final_data=complete_stress_analysis(
                measured_wavelengths=measured_wavelengths,
                initial_wavelengths=initial_wavelengths,
                KT=KT,
                constitutive_matrix=D_list,
                adjustment_matrix=A_list
            )


            stress_data=final_data['主应力大小']
            horizontal=final_data['正应力大小'][:3].tolist()

            stress.append({
                'stress':{
                    'σ1':stress_data[0],
                    'σ2':stress_data[1],
                    'σ3':stress_data[2]
                },
                'direction':final_data['主应力方向'],
                'horizontal':{
                    'σx':horizontal[0][0],
                    'σy':horizontal[1][0],
                    'σz':horizontal[2][0]
                },
                'create_time':row.create_time
            })
            stress_info['sensor']=stress
        data_list.append(stress_info)

    return Success(data=data_list)


